package com.wetool.wechat.service;

import com.wetool.common.auth.modle.AccountDto;
import com.wetool.common.model.LoginDto;
import com.wetool.common.model.Message;
import com.wetool.common.model.Result;
import com.wetool.common.model.UserType;
import com.wetool.common.wechat.WechatSignUpRequest;
import com.wetool.wechat.feign.AuthFeignClient;
import com.wetool.wechat.feign.WechatOpenPlatformFeignClient;
import com.wetool.wechat.model.open.WechatAccessTokenResponse;
import com.wetool.wechat.model.open.WechatOpenUserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Base64;
import java.util.LinkedHashMap;

@Service
public class WechatOAuthService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WechatOAuthService.class);

    @Value("${wechat.web-application.appId}")
    private String appId;

    @Value("${wechat.web-application.appSecret}")
    private String appSecret;

    @Autowired
    private WechatOpenPlatformFeignClient wechatOpenPlatformFeignClient;

    @Autowired
    private AuthFeignClient authFeignClient;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 获取开放平台accessToken
     *
     * @param code
     * @return
     */
    public WechatAccessTokenResponse accessToken(String code) {
        String grantType = "authorization_code";
        WechatAccessTokenResponse accessToken = wechatOpenPlatformFeignClient.accessToken(this.appId, this.appSecret, code, grantType);
        return accessToken;
    }

    /**
     * 访问微信服务器获取用户详细信息(包含UnionId)
     *
     * @param accessToken
     * @param openId
     * @return
     */
    public WechatOpenUserInfo getUserInfo(String accessToken, String openId) {
        WechatOpenUserInfo wechatOpenUserInfo = wechatOpenPlatformFeignClient.userInfo(accessToken, openId);
        return wechatOpenUserInfo;
    }

    /**
     * 向微兔认证服务器验证当前微信用户
     *
     * @param userId 微兔用户id
     * @param role   角色名称
     * @return 成功，返回用户信息；失败，返回失败原因
     */
    public Message<?> verifyWechatUser(long userId, UserType role) {
        //TODO 认证用户角色
        ResponseEntity<Message<?>> responseEntity = this.authFeignClient.verifyUser(userId, role.getKey());
        LOGGER.info("微信用户登录feign结果：{}", responseEntity.getBody());
        //成功则返回用户名与密码
        if (responseEntity.getBody().getCode() == Result.SUCCESS.getCode()) {
            LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) responseEntity.getBody().getData();

            String username = (String) map.get("username");
            String password = (String) map.get("password");

            Message<?> message = new Message<>(Result.SUCCESS, new LoginDto(username, password));

            return message;
        } else {
            //否则返回失败
            return responseEntity.getBody();
        }
    }


    /**
     * 微信用户注册
     *
     * @param request
     * @return
     */
    public Message<?> signUpWechatUser(WechatSignUpRequest request) {

        String username = request.getUserType().name() + "_" + request.getMobile();

        AccountDto accountDto = new AccountDto(username, request.getPassword(), request.getMobile(), request.getUserType().ordinal(), request.getUserType().getKey());

        ResponseEntity<Message<?>> responseEntity = this.authFeignClient.signUpUser(accountDto);

        return responseEntity.getBody();
    }

    /**
     * 构造请求body参数（授权类型：password）
     *
     * @param grantType
     * @param username
     * @param password
     * @return
     */
    private LinkedMultiValueMap<String, String> body(String grantType, String username, String password) {
        LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
        map.add("grant_type", grantType);
        map.add("username", username);
        map.add("password", password);
        return map;
    }

    /**
     * 构造请求头
     *
     * @return
     */
    private HttpHeaders headers() {
        String plainCredentials = "admin:admin";
        String base64Credentials = Base64.getEncoder().encodeToString(plainCredentials.getBytes());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + base64Credentials);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return headers;
    }
}
